import { createReducer } from 'reduxsauce'
import { REHYDRATE } from 'redux-persist/es/constants'
import { AddressDeleteActionITF, AddressStateITF } from '@REDUXITF/address'
import {
  CREATE_SHIP_ADDRESS,
  DELETE_SHIP_ADDRESS,
  GET_SHIP_ADDRESS,
  SET_SHIP_ADDRESS,
  UPDATE_SHIP_ADDRESS
} from '@ACTIONS/address'
import { ShipAddressITF } from '@INTERFACES/Address'

const INITIAL_STATE: AddressStateITF = {
  shipAddress: [],
  selectedAddress: null,
  refreshing: true,
  loading: false,
  canLoadMore: false
}

const rehydrate = (state: AddressStateITF, { payload }: { payload: { address: AddressStateITF } }) => {
  if (payload && payload.address) {
    return { ...INITIAL_STATE, ...payload.address }
  }
  return { ...state }
}

export default createReducer(INITIAL_STATE, {
  [REHYDRATE]: rehydrate,
  [GET_SHIP_ADDRESS.REQUEST]: (state, { isInit }: { isInit: boolean }) => ({
    ...state,
    shipAddress: isInit ? [] : state.shipAddress,
    canLoadMore: true,
    loading: true,
    refreshing: isInit ? true : state.refreshing
  }),
  [GET_SHIP_ADDRESS.SUCCESS]: (state,
    { data, canLoadMore, isInit, isSetDefaultAddress }: {
    data: ShipAddressITF[], canLoadMore: boolean, isInit: boolean, isSetDefaultAddress: boolean }) => {
    const list = isInit ? data : [...state.shipAddress, ...data]
    const newSelectAddress = isSetDefaultAddress ? data[0] : state.selectedAddress
    return ({
      ...state,
      loading: false,
      shipAddress: list,
      canLoadMore,
      refreshing: false,
      selectedAddress: newSelectAddress || null
    })
  },
  [GET_SHIP_ADDRESS.FAILURE]: state => ({
    ...state,
    refreshing: false,
    loading: false
  }),
  [DELETE_SHIP_ADDRESS.SUCCESS]: (state, { p8Id } : AddressDeleteActionITF) => {
    const newShipAddress = state.shipAddress?.filter(item => item.p8Id !== p8Id)
    const isDeleteAddress = state.selectedAddress?.p8Id === p8Id
    let newAddress = state.selectedAddress
    if (isDeleteAddress) {
      newAddress = newShipAddress?.[0] || null
    }
    return ({
      ...state,
      selectedAddress: newAddress,
      shipAddress: newShipAddress || [],
    })
  },
  [UPDATE_SHIP_ADDRESS.SUCCESS]: (state, { address } : { address: ShipAddressITF }) => {
    const newShipAddress = state.shipAddress?.map(item => (item.p8Id !== address.p8Id ? item : ({ ...item, ...address })))
    const newAddress = state.selectedAddress?.p8Id === address.p8Id ? address : state.selectedAddress
    return ({
      ...state,
      selectedAddress: newAddress,
      shipAddress: newShipAddress || [],
    })
  },
  [CREATE_SHIP_ADDRESS.SUCCESS]: (state, { address, isSelected } : { address: ShipAddressITF, isSelected: boolean }) => {
    const newShipAddress = [address, ...state.shipAddress]
    const newAddress = isSelected ? address : state.selectedAddress
    return ({
      ...state,
      selectedAddress: newAddress,
      shipAddress: newShipAddress || [],
    })
  },
  [SET_SHIP_ADDRESS.REQUEST]: (state, { address } : { address: ShipAddressITF | null }) => ({
    ...state,
    selectedAddress: address,
  }),
})
